/**
 * 將原先的圖片加上文字的工具
 */
package kg.tool.image;

import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

import kg.tool.string.RandomString;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;


/**
 * 將原先的圖片加上文字
 * @author Kahiro
 * @since Java 6 之後才支援此系統
 */
public class AuthenticationGraphBuilder {
	private File bgFile;
	private Font defaultFont = new Font("", Font.BOLD, 28);
	private AuthenticationGraphBuilder(){};
	
	private static final Pattern FILE_NAME_PATTERN = Pattern.compile(".*\\.([\\w]+)$");
	
	public static AuthenticationGraphBuilder createBuilder(String fileName) throws FileNotFoundException{
		return createBuilder(new File(fileName));
	}
	
	public static AuthenticationGraphBuilder createBuilder(File file) throws FileNotFoundException{
		if(file == null || !file.exists()){
			throw new FileNotFoundException("background file does not exist!!");
		}
		AuthenticationGraphBuilder gb = new AuthenticationGraphBuilder();
		gb.bgFile = file;
		
		return gb;
	}

	/**
	 * 產生附帶文字的圖片的 ByteArrayOutputStream 物件
	 * @param inputString
	 * @return
	 */
	public ByteArrayOutputStream getGraphWithString(String inputString){
		return getGraphWithString(inputString, 0, 0);
	}
	
	/**
	 * 產生附帶文字的圖片的 ByteArrayOutputStream 物件
	 * @param inputString
	 * @param x
	 * @param y
	 * @return
	 */
	public ByteArrayOutputStream getGraphWithString(String inputString, int x, int y){
		return getGraphWithString(inputString, x, y, 0, 0);
	}
	
	/**
	 * 產生附帶文字的圖片的 ByteArrayOutputStream 物件
	 * @param inputString
	 * @param x
	 * @param y
	 * @param iWidth
	 * @param iHeight
	 * @return
	 */
	public ByteArrayOutputStream getGraphWithString(String inputString, int x, int y, int iWidth, int iHeight){
		try{
			
			Image image = ImageIO.read(bgFile);
			
			if(iWidth == 0 && iHeight == 0){
				iWidth = image.getWidth(null);
				iHeight = image.getHeight(null);
			}
			
			if(y == 0){
				y = iHeight * 4 / 5;
			}
			
			BufferedImage bufImg = new BufferedImage(54,51,BufferedImage.TYPE_INT_RGB);
			Graphics2D g2d = (Graphics2D) bufImg.getGraphics();
			g2d.setFont(defaultFont);
			g2d.drawImage(image, 0, 0, iWidth, iHeight,null);
			g2d.drawString(inputString, x, y);

			ByteArrayOutputStream boutstream = new ByteArrayOutputStream();
			JPEGImageEncoder enc = JPEGCodec.createJPEGEncoder(boutstream);
		    JPEGEncodeParam params = JPEGCodec.getDefaultJPEGEncodeParam(bufImg);
		    enc.encode(bufImg, params);
		    return boutstream;
		}catch(IOException ioe){
			ioe.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 產生附帶文字的圖片的File物件
	 * @param inputString
	 * @param outputPath
	 * @return
	 */
	public File getFileOfGraphWithString(String inputString, String outputPath){
		return getFileOfGraphWithString(inputString, outputPath, 0, 0);
	}
	
	
	/**
	 * 產生附帶文字的圖片的File物件
	 * @param inputString
	 * @param outputPath
	 * @param x
	 * @param y
	 * @return
	 */
	public File getFileOfGraphWithString(String inputString, String outputPath, int x, int y){
		return getFileOfGraphWithString(inputString, outputPath, x, y, 0, 0);
	}
	
	/**
	 * 產生附帶文字的圖片的File物件
	 * @param inputString
	 * @param outputPath
	 * @param x
	 * @param y
	 * @param iWidth
	 * @param iHeight
	 * @return
	 */
	public File getFileOfGraphWithString(String inputString, String outputPath, int x, int y, int iWidth, int iHeight){
		try{
			Image image = ImageIO.read(bgFile);
			
			if(iWidth == 0 && iHeight == 0){
				iWidth = image.getWidth(null);
				iHeight = image.getHeight(null);
			}
			
			if(y == 0){
				y = iHeight * 4 / 5;
			}
			BufferedImage bufImg = new BufferedImage(iWidth, iHeight,BufferedImage.TYPE_INT_RGB);
			Graphics2D g2d = (Graphics2D) bufImg.getGraphics();
			g2d.setFont(defaultFont);
			g2d.drawImage(image, 0, 0, iWidth, iHeight,null);
			g2d.drawString(inputString, x, y);
			File outputFile = new File(outputPath);
			
			Matcher matcher = FILE_NAME_PATTERN.matcher(bgFile.getName());
			if(matcher.matches()){
				ImageIO.write(bufImg, matcher.group(1), outputFile);
				System.out.println("output image successfully!!");
				return outputFile;
			}else{
				throw new IOException("file name \"" + bgFile.getName() + "\" is illegal!!");
			}
			
			
		}catch(IOException ioe){
			ioe.printStackTrace();
		}
		return null;
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try{
		AuthenticationGraphBuilder gb = AuthenticationGraphBuilder.createBuilder("D:\\temp\\pic\\bg.jpg");
		//方法一
//		gb.getFileOfGraphWithString(kh.com.cht.util.RandomString.getRandomAlphaNumericUpperCase(5), "D:\\temp\\pic\\bgTest.jpg");
		
		
		//方法二
		String fileName = "D:\\temp\\pic\\bgTest.jpg";
	    FileOutputStream fimage = new FileOutputStream(new File(fileName));
	    ByteArrayOutputStream boutstream = gb.getGraphWithString(RandomString.getInstance().getRandomAlphaNumericUpperCase(5));
			boutstream.writeTo(fimage);
			fimage.close();
	    
		}catch(FileNotFoundException e){
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
